home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / nos_kit3.zip / TNC_ASH.ZIP / VDS_KISS.ASM < prev    next >
Assembly Source File  |  1987-08-25  |  48KB  |  1,821 lines

  1. ; *********************************************************************
  2. ; **  KISS Protocol Program for stock VADCG/ASHBY-2716   KISS V1.03  **
  3. ; **              By: Mike Bruski, AJ9X                    08FEB87   **
  4. ; *********************************************************************
  5.  
  6. ;     Change History:
  7. ;       When       Who         What
  8. ;    26JAN87    AJ9X         Initial Version (V1.00)
  9. ;    31JAN87    AJ9X        Removed auto baud rate detection &
  10. ;                interval timer driven by 8253 (V1.01)
  11. ;    07FEB87    AJ9X        Send last character and release cell
  12. ;                on transmitted async. frames (V1.02)
  13. ;    08FEB87    AJ9X        Disabled early end of frame interrupt
  14. ;                from 8273 to prevent transmitter
  15. ;                shutdown prior to sending CRC and
  16. ;                closing flag (V1.03)
  17. ;    10SEP87       PA0GRI    Add a state in the async output to send
  18. ;                a FEND char in front of a frame.
  19. ;    PAGE
  20.  
  21. ;
  22. ;    8250 SIO Controller Equates
  23.  
  24. ;    Registers:
  25.  
  26. RBR    EQU    0        ; RECEIVE BUFFER REGISTER            [R]
  27. THR    EQU    0        ; TRANSMIT HOLDING REGISTER          [W]
  28. DLL    EQU    0        ; DRIVER LATCH (LSB)                 [W]
  29. DLM    EQU    1        ; DRIVER LATCH (MSB)                 [W]
  30. IER    EQU    1        ; INTERRUPT ENABLE REGISTER          [W]
  31. IIR    EQU    2        ; INTERRUPT IDENTIFICATION REGISTER  [R]
  32. LCR    EQU    3        ; LINE CONTROL REGISTER            [R/W]
  33. MCR    EQU    4        ; MODEM CONTROL REGISTER           [R/W]
  34. LSR    EQU    5        ; LINE STATUS REGISTER             [R/W]
  35. MSR    EQU    6        ; MODEM STATUS REGISTER            [R/W]
  36.  
  37. ;    Equates for Interrupt Enable Register
  38.  
  39. ERI    EQU    00000001B    ; ENABLE RECEIVE DATA INTERRUPTS
  40. ETI    EQU    00000010B    ; ENABLE TRANSMIT DATA INTERRUPTS
  41. ELI    EQU    00000100B    ; ENABLE LINE STATUS INTERRUPTS
  42. EMI    EQU    00001000B    ; ENABLE MODEM STATUS INTERRUPTS
  43.  
  44. ;    Equates for Line Status Register
  45.  
  46. DR    EQU    00000001B    ; DATA READY
  47. OE    EQU    00000010B    ; OVERRUN ERROR
  48. PE    EQU    00000100B    ; PARITY ERROR
  49. FE    EQU    00001000B    ; FRAMING ERROR
  50. BI    EQU    00010000B    ; BREAK INTERRUPT
  51. THRE    EQU    00100000B    ; TRANSMIT HOLDING REGISTER EMPTY
  52. TSRE    EQU    01000000B    ; TRANSMIT SHIFT REGISTER EMPTY
  53.  
  54. ;    Equates for Modem Status Register
  55.  
  56. DCTS    EQU    00000001B    ; DELTA CLEAR-TO-SEND
  57. DDSR    EQU    00000010B    ; DELTA DATA-SET-READY
  58. TERI    EQU    00000100B    ; TRAILING EDGE OF RING INDICATOR
  59. DCD    EQU    00001000B    ; DELTA CARRIER DETECT
  60. TCTS    EQU    00010000B    ; TERMINAL CLEAR-TO-SEND
  61. TDSR    EQU    00100000B    ; TERMINAL DATA-SET-READY
  62. TRI    EQU    01000000B    ; TERMINAL RING INDICATOR
  63. TCD    EQU    10000000B    ; TERMINAL CARRIER DETECT
  64.  
  65. ;    Equates for Line Control Register
  66.  
  67. D5    EQU    00000000B    ; WORD LENGTH = 5 BITS
  68. D6    EQU    00000001B    ; WORD LENGTH = 6 BITS
  69. D7    EQU    00000010B    ; WORD LENGTH = 7 BITS
  70. D8    EQU    00000011B    ; WORD LENGTH = 8 BITS
  71. S1    EQU    00000000B    ; STOP BITS = 1
  72. S2    EQU    00000100B    ; STOP BITS = 2
  73. NP    EQU    00000000B    ; NO PARITY
  74. PEN    EQU    00001000B    ; PARITY ENABLE
  75. OP    EQU    00000000B    ; ODD PARITY
  76. EP    EQU    00010000B    ; EVEN PARITY SELECT
  77. STP    EQU    00100000B    ; STICK PARITY
  78. SB    EQU    01000000B    ; SET BREAK
  79. DLA    EQU    10000000B    ; DIVISOR LATCH ACCESS
  80.  
  81. ;    Equates for Modem Control Register
  82.  
  83. ADTR    EQU    00000001B    ; ASYNCHRONOUS DATA-TERMINAL-READY
  84. ARTS    EQU    00000010B    ; ASYNCHRONOUS REQUEST-TO-SEND
  85. OUT1    EQU    00000100B    ; ASYNCHRONOUS CARRIER DETECT (LOOP=RI)
  86. OUT2    EQU    00001000B    ; NO CONNECTION ON VADCG (LOOP=CD)
  87. LOOP    EQU    00010000B    ; LOOPBACK DIAGNOSTIC ENABLE
  88.  
  89. ;    Equates for Interrupt Identification Register
  90.  
  91. AIPM    EQU    00000001B    ; ASYNC INT. PENDING MASK
  92. ;                   INTERRUPT IS PENDING IF NOT SET
  93. IIM    EQU    00000110B    ; INTERRUPT IDENTIFICATION MASK
  94. RLSI    EQU    00000110B    ; RECEIVER LINE STATUS INTERRUPT
  95. RDAI    EQU    00000100B    ; RECEIVED DATA AVAILABLE INTERRUPT
  96. TREI    EQU    00000010B    ; TRANSMIT HOLDING REG. EMPTY INTERRUPT
  97. MSI    EQU    00000000B    ; MODEM STATUS INTERRUPT
  98. ;    PAGE
  99.  
  100. ;
  101. ;    8273 HDLC Controller Equates
  102.  
  103. ;    Registers:
  104.  
  105. STAT73    EQU    10H        ; STATUS REGISTER                    [R]
  106. CMND73    EQU    10H        ; COMMAND REGISTER                   [W]
  107. PARM73    EQU    11H        ; PARAMETER REGISTER                 [W]
  108. RESL73    EQU    11H        ; RESULTS REGISTER                   [R]
  109. TEST73    EQU    12H        ; TEST REGISTER                      [W]
  110. TXIR73    EQU    12H        ; TRANSMIT INTERRUPT RESULTS REGISTER[R]
  111. RXIR73    EQU    13H        ; RECEIVE INTERRUPT RESULTS REGISTER [R]
  112. TXDR73    EQU    18H        ; TRANSMIT DATA REGISTER             [W]
  113. RXDR73    EQU    20H        ; RECEIVE DATA REGISTER              [R]
  114.  
  115. ;    Equates for STAT73
  116.  
  117. TXIRA    EQU    00000001B    ; TRANSMIT INTERRUPT RESULTS AVAILABLE
  118. RXIRA    EQU    00000010B    ; RECEIVE INTERRUPT RESULTS AVAILABLE
  119. TINTP    EQU    00000100B    ; TRANSMIT INTERRUPT STILL PENDING
  120. RINTP    EQU    00001000B    ; RECEIVE INTERRUPT STILL PENDING
  121. CRBF    EQU    00010000B    ; COMMAND RESULTS BUFFER FULL
  122. CPBF    EQU    00100000B    ; COMMAND PARAMETER BUFFER FULL
  123. CBF    EQU    01000000B    ; COMMAND BUFFER FULL
  124. CBSY    EQU    10000000B    ; COMMAND BUFFER BUSY
  125.  
  126. ;    Equates for TXIR73
  127.  
  128. EXI    EQU    00001100B    ; EARLY TRANSMIT INTERRUPT
  129. FTC    EQU    00001101B    ; FRAME TRANSMISSION COMPLETE
  130. DMAU    EQU    00001110B    ; DMA UNDERRUN (not used)
  131. CTSE    EQU    00001111B    ; CLEAR-TO-SEND ERROR
  132. ATC    EQU    00010000B    ; ABORT TRANSMISSION COMPLETE
  133.  
  134. ;    Equates for RXIR73
  135.  
  136. CRCE    EQU    00000011B    ; CRC ERROR
  137. FAD    EQU    00000100B    ; FRAME ABORT DETECTED
  138. IFD    EQU    00000101B    ; IDLE FLAG DETECTED
  139. EOPD    EQU    00000110B    ; EOP DETECTED (not used)
  140. SFD    EQU    00000111B    ; SHORT FRAME DETECTED (< 32 BITS)
  141. DMAO    EQU    00001000B    ; DMA OVERRUN
  142. MBO    EQU    00001001B    ; MEMORY BUFFER OVERFLOW
  143. CDF    EQU    00001010B    ; CARRIER DETECT FAILURE
  144. RIO    EQU    00001011B    ; RECEIVE INTERRUPT OVERRUN
  145.  
  146. ;    Equates for PORT A (input)
  147.  
  148. MCTS    EQU    00000001B    ; MODEM CLEAR-TO-SEND
  149. MCD    EQU    00000010B    ; MODEM CARRIER DETECT
  150. PA2    EQU    00000100B    ; SPARE PORT INPUT
  151. PA3    EQU    00001000B    ; SPARE PORT INPUT
  152. PA4    EQU    00010000B    ; SPARE PORT INPUT
  153.  
  154. ;    Equates for PORT B (output)
  155.  
  156. MRTS    EQU    00000001B    ; MODEM REQUEST-TO-SEND
  157. PB1    EQU    00000010B    ; SPARE PORT OUTPUT
  158. PB2    EQU    00000100B    ; SPARE PORT OUTPUT
  159. PB3    EQU    00001000B    ; SPARE PORT OUTPUT
  160. PB4    EQU    00010000B    ; SPARE PORT OUTPUT
  161. FD    EQU    00100000B    ; FLAG DETECT
  162. ;    PAGE
  163.  
  164. ;
  165. ;    8253 Interval Timer Equates (VDS-1 only)
  166.  
  167. ;    Registers:
  168.  
  169. PIT0    EQU    28H        ; COUNTER PORT 0 (8273 BAUD RATE)
  170. PIT1    EQU    29H        ; COUNTER PORT 1 (8085 TRAP)
  171. PIT2    EQU    2AH        ; COUNTER PORT 2
  172. ITCP    EQU    2BH        ; INTERVAL TIMER CONTROL PORT
  173.  
  174. ;    Equates for ITCP (control word)
  175.  
  176. ;    Register selection field
  177. C0    EQU    00000000B    ; COUNTER 0
  178. C1    EQU    01000000B    ; COUNTER 1
  179. C2    EQU    10000000B    ; COUNTER 2
  180.  
  181. ;    Read/Load control field
  182. LC    EQU    00000000B    ; LATCH COUNT
  183. RLL    EQU    00010000B    ; READ/LOAD LSB ONLY
  184. RLM    EQU    00100000B    ; READ/LOAD MSB ONLY
  185. RLB    EQU    00110000B    ; READ/LOAD LSB FIRST, MSB NEXT
  186.  
  187. ;    Mode control field
  188. MD0    EQU    00000000B    ; MODE 0, TIMED INTERRUPT
  189. MD1    EQU    00000010B    ; MODE 1, RETRIGGERABLE ONE SHOT
  190. MD2    EQU    00000100B    ; MODE 2, RATE GENERATOR
  191. MD3    EQU    00000110B    ; MODE 3, SQUARE WAVE GENERATOR
  192. MD4    EQU    00001000B    ; MODE 4, SOFTWARE TRIGGERED STROBE
  193. MD5    EQU    00001010B    ; MODE 5, HARDWARE TRIGGERED STROBE
  194.  
  195. ;    Counter Type field
  196. BIN    EQU    00000000B    ; 16 BIT BINARY
  197. BCD    EQU    00000001B    ;  4 DECADE BCD
  198.  
  199. ;    Equates for PIT0 (Synchronous Baud Rate Values)
  200.  
  201. SBR9600    EQU    4        ; 9600 baud
  202. SBR4800    EQU    8        ; 4800 baud
  203. SBR2400    EQU    16        ; 2400 baud
  204. SBR1200    EQU    32        ; 1200 baud (default)
  205. SBR600    EQU    64        ;  600 baud
  206. SBR300    EQU    128        ;  300 baud
  207.  
  208. ;    Equates for PIT1 (Cyclic Timer) - NOT USING THIS YET
  209. ;       Input = 38.4Khz from pin 4 of U40
  210.  
  211. MS100    EQU    3840        ; 100ms timer value 
  212. MS50    EQU    1920        ;  50ms timer value
  213. MS20    EQU    768        ;  20ms timer value
  214. MS10    EQU    384        ;  10ms timer value (default)
  215.  
  216. ;  Use these guys for S/W timing (now for all VADCG & ASHBY)
  217. IC100    EQU    2297        ; Interval count for 100ms
  218. IC10    EQU    230        ; Interval count for 10ms
  219.  
  220. ;    Equates for PIT2 (Random Number Generator)
  221. ;    Input = 38.4Khz from pin 4 of U40
  222.  
  223. SEED    EQU    32767
  224. ;    PAGE
  225.  
  226. ;
  227. ;    8085 CPU Interrupt Mask Register Equates
  228.  
  229. ACD    EQU    00000001B    ; RST5.5, ASYNC. INTERRUPTS DISABLED
  230. STD    EQU    00000010B    ; RST6.5, SYNC. XMTR INT. DISABLED
  231. SRD    EQU    00000100B    ; RST7.5, SYNC. RCVR INT. DISABLED
  232. MSE    EQU    00001000B    ; INTERRUPT MASK ENABLED
  233.  
  234. ;
  235. ;    Special Character Equates
  236. EOS    EQU    00H
  237. LF    EQU    0AH
  238. CR    EQU    0DH
  239. COMMA    EQU    2CH
  240. PERIOD    EQU    2EH
  241. FEND    EQU    0C0H
  242. FESC    EQU    0DBH
  243. TFEND    EQU    0DCH
  244. TFESC    EQU    0DDH
  245.  
  246. ;
  247. ;    End Action (Event) Flags
  248. SRFC    EQU    00000001B    ; SYNC. RECEIVER FRAME COMPLETION
  249. ARFC    EQU    00000010B    ; ASYNC. RECEIVER FRAME COMPLETION
  250. STFC    EQU    00000100B    ; SYNC. TRANSMITTER FRAME COMPLETION
  251. ATFC    EQU    00001000B    ; ASYNC. TRANSMITTER FRAME COMPLETION
  252. EXTI    EQU    00010000B    ; EXPIRED TIMER
  253. SRDD    EQU    00100000B    ; SYNC. RECEIVER DISCARDING DATA
  254. ARDD    EQU    01000000B    ; ASYNC. RECEIVER DISCARDING DATA
  255.  
  256. ;
  257. ;    Miscellaneous Equates
  258. WDVAL    EQU    220        ; DEFAULT WATCH DOG DELAY FOR 1200 BAUD
  259. ;    PAGE
  260.  
  261. ;
  262. ;    Static Random Access Memory (SRAM) Equates
  263.  
  264. ;    LORAM    HIRAM    CONFIGURATION
  265. ;
  266. ;    1000H    1FFFH  *ASHBY with 2716 ROMs or Standard VADCG
  267. ;    2000H    2FFFH    ASHBY with 2732 ROMs
  268. ;    7000H    7FFFH    VADCG with California memory mods
  269. ;    8000H    8FFFH    VADCG with early AMRAD memory mods
  270. ;    8000H    9FFFH    VADCG with VDS-1 (8K RAM)
  271. ;    8000H    FFFFH    VADCG with VDS-1 (32K RAM)
  272. ;    
  273.  
  274. LORAM    EQU    8000H        ; BEGINNING OF SRAM
  275. HIRAM    EQU    9FFFH        ; END OF SRAM
  276. STACK    EQU    LORAM+64H    ; BEGINNING OF PROGRAM STACK
  277. EA$FLG    EQU    STACK+2        ; END ACTION FLAGS
  278.  
  279. ;    Interval Timer Variables
  280. PVAL    EQU    EA$FLG+1    ; PERSISTENCE VALUE
  281. SVAL    EQU    PVAL+1        ; SLOT-TIME VALUE
  282. RVAL    EQU    SVAL+1        ; RELAY DELAY VALUE
  283. TVAL    EQU    RVAL+1        ; SQUELCH TAIL DELAY VALUE
  284. TICKS    EQU    TVAL+1        ; TICK COUNTER FOR S/W TIMING
  285. IT$FLG    EQU    TICKS+2        ; 0 = INACTIVE, 1 = ACTIVE
  286. IT$VAL    EQU    IT$FLG+1    ; CURRENT TIMER VALUE
  287. IT$STA    EQU    IT$VAL+2    ; CURRENT TIMER STATE
  288.  
  289. ;    Asynchronous Receiver Variables
  290. AR$HC    EQU    IT$STA+1    ; CURRENT FRAME HEAD
  291. AR$BP    EQU    AR$HC+2        ; CURRENT BUFFER POINTER
  292. AR$FSZ    EQU    AR$BP+2        ; CURRENT FRAME SIZE
  293. AR$FH    EQU    AR$FSZ+2    ; COMPLETED FRAME HEAD
  294. AR$FS    EQU    AR$FH+2        ; COMPLETED FRAME SIZE
  295. AR$STA    EQU    AR$FS+2        ; CURRENT MACHINE STATE
  296.  
  297. ;    Asynchronous Transmitter Variables
  298. AT$BP    EQU    AR$STA+1    ; CURRENT BUFFER POINTER
  299. AT$QS    EQU    AT$BP+2        ; QUEUE SIZE
  300. AT$QR    EQU    AT$QS+1        ; QUEUE READ POINTER
  301. AT$QW    EQU    AT$QR+2        ; QUEUE WRITE POINTER
  302. AT$STA    EQU    AT$QW+2        ; CURRENT MACHINE STATE
  303.  
  304. ;    Synchronous Receiver Variables
  305. SR$HC    EQU    AT$STA+1    ; CURRENT FRAME HEAD
  306. SR$BP    EQU    SR$HC+2        ; CURRENT BUFFER POINTER
  307. SR$FR    EQU    SR$BP+2        ; CURRENT FRAME RESULTS
  308. SR$STA    EQU    SR$FR+1        ; CURRENT MACHINE STATE
  309.  
  310. ;    Synchronous Transmitter Variables
  311. ST$BP    EQU    SR$STA+1    ; CURRENT BUFFER POINTER
  312. ST$FR    EQU    ST$BP+2        ; CURRENT FRAME RESULTS
  313. ST$QS    EQU    ST$FR+1        ; QUEUE SIZE
  314. ST$QR    EQU    ST$QS+1        ; QUEUE READ POINTER
  315. ST$QW    EQU    ST$QR+2        ; QUEUE WRITE POINTER
  316.  
  317. ;    Synchronous Command Buffers
  318. SRACT    EQU    ST$QW+2        ; RECEIVER ACTIVATION COMMAND
  319. STACT    EQU    SRACT+4        ; TRANSMITTER ACTIVATION COMMAND
  320.  
  321. ;    Asynchronous Transmitter Queue
  322. AT$QT    EQU    STACT+4        ; TOP OF QUEUE
  323. AT$QB    EQU    AT$QT+(2*64)    ; BOTTOM OF QUEUE
  324.  
  325. ;    Synchronous Transmitter Queue
  326. ST$QT    EQU    AT$QB+2        ; TOP OF QUEUE
  327. ST$QB    EQU    ST$QT+(4*64)    ; BOTTOM OF QUEUE
  328.  
  329. ;    Buffer area
  330. FL$HC    EQU    ST$QB+4
  331. NCELL    EQU    (HIRAM-FL$HC+2)/128
  332. BAREA    EQU    (HIRAM-NCELL*128)+1 ; BEGINNING OF BUFFER AREA
  333. NLIST    EQU    BAREA-2        ; # OF AVAILABLE CELLS IN FREE LIST
  334. ;    PAGE
  335.  
  336. BASE    EQU    0
  337.     ORG    BASE        ; PROGRAM ORIGIN
  338.  
  339. ;
  340. ;    Here we begin -
  341. ;    A good place to start is with the interrupt vectors
  342.  
  343. ;
  344. ;    RST0 - [H/W AND S/W INTERRUPT]
  345. ;    ENTER HERE ON POWER UP AND WHEN THE RESET
  346. ;    BUTTON IS SMASHED TO INITIALIZE THE H/W
  347. ;    AND MEMORY.  MIGHT ALSO VECTOR HERE IN S/W
  348. ;    IF EVERYTHING IS SO MESSED UP THE TNC CAN'T
  349. ;    FUNCTION CORRECTLY.
  350.  
  351. RST0    EQU    $        ; RESTART (WARM & COLD)
  352.     JMP    INIT
  353.  
  354.     ORG    BASE+08H
  355.  
  356. ;
  357. ;    RST1 - [S/W INTERRUPT]
  358. ;    ENTER HERE TO RETURN FROM AN INTERRUPT.  THE FIRST
  359. ;    ITEM ON THE STACK WILL BE A RETURN ADDRESS TO THE
  360. ;    RST INSTRUCTION WHICH GOT US HERE SO IT GETS WASTED.
  361. ;    NEXT THE PROGRAM STATUS WORD (ACCUMULATOR & FLAGS)
  362. ;    ARE RESTORE, INTERRUPTS ARE RE-ENABLED AND THE REST
  363. ;    IS HISTORY.
  364.  
  365. RST1    EQU    $
  366.     POP    PSW        ; PURGE BOGUS ADDRESS FROM STACK
  367.     POP    PSW        ; RESTORE PROGRAM STATUS WORD
  368.     EI            ; UNGATE INTERRUPTS
  369.     RET            ; RETURN TO POINT OF INTERRUPT
  370.  
  371.     ORG    BASE+10H
  372.  
  373. ;
  374. ;    RST2 - [S/W INTERRUPT]
  375. ;    NO FUNCTION
  376.  
  377. RST2    EQU    $
  378.     RET
  379.  
  380.     ORG    BASE+18H
  381.  
  382. ;
  383. ;    RST3 - [S/W INTERRUPT]
  384. ;    NO FUNCTION
  385.  
  386. RST3    EQU    $
  387.     RET
  388.  
  389.     ORG    BASE+20H
  390.  
  391. ;
  392. ;    RST4 - [S/W INTERRUPT]
  393. ;    NO FUNCTION
  394.  
  395. RST4    EQU    $
  396.     RET
  397.  
  398.     ORG    BASE+24H
  399.  
  400. ;
  401. ;    TRAP - [NON MASKABLE H/W INTERRUPT]
  402. ;    NOT USED
  403.  
  404. TRAP    EQU    $
  405.     EI
  406.     RET
  407.  
  408.     ORG    BASE+28H
  409.  
  410. ;
  411. ;    RST5 - [S/W INTERRUPT]
  412. ;    NO FUNCTION
  413.  
  414. RST5    EQU    $
  415.     RET
  416.  
  417.     ORG    BASE+2CH
  418.  
  419. ;
  420. ;    RST5.5 - [MASKABLE H/W INTERRUPT]
  421. ;    VECTOR HERE WHEN A SIGNAL IS DETECTED ON PIN 9 OF
  422. ;    THE 8085.  THE 8250 WILL ASSERT THIS PIN WHEN ONE
  423. ;    OF THE FOLLOWING OCCURS; TRANSMIT BUFFER EMPTY,
  424. ;    RECEIVE CHARACTER AVAILABLE, RECEIVER OVERRUN,
  425. ;    RECEIVER PARITY ERROR, RECEIVER FRAMING ERROR,
  426. ;    BREAK INTERRUPT, DELTA CTS, DELTA DSR, RING INDICATE
  427. ;    OR RECEIVE LINE SIGNAL DETECT.
  428.  
  429. RST55    EQU    $
  430.     JMP    AIRC    ; GOTO ASYNC. INTERRUPT RESPONSE CODE
  431.  
  432.     ORG    BASE+30H
  433.  
  434. ;
  435. ;    RST6 - [S/W INTERRUPT]
  436. ;    NO FUNCTION
  437.  
  438. RST6    EQU    $
  439.     RET
  440.  
  441.     ORG    BASE+34H
  442.  
  443. ;
  444. ;    RST6.5 - [MASKABLE H/W INTERRUPT]
  445. ;    VECTOR HERE WHEN A SIGNAL IS DETECTED ON PIN 8 OF
  446. ;    THE 8085.  THE 8273 WILL ASSERT THIS PIN WHEN THE
  447. ;    SYNCHRONOUS TRANSMITTER REQUIRES SERVICE.
  448.  
  449. RST65    EQU    $
  450.     JMP    STIRC    ; GOTO SYNC. XMTR INTERRUPT RESPONSE CODE
  451.  
  452.     ORG    BASE+38H
  453.  
  454. ;
  455. ;    RST7 - [S/W INTERRUPT]
  456. ;    NO FUNCTION
  457.  
  458. RST7    EQU    $
  459.     RET
  460.  
  461.     ORG    BASE+3CH
  462.  
  463. ;
  464. ;    RST7.5 - [MASKABLE H/W INTERRUPT]
  465. ;    VECTOR HERE WHEN A SIGNAL IS DETECTED ON PIN 7 OF
  466. ;    THE 8085.  THE 8273 WILL ASSERT THIS PIN WHEN THE
  467. ;    SYNCHRONOUS RECEIVER REQUIRES SERVICE.
  468.  
  469. RST75    EQU    $
  470.     JMP    SRIRC    ; GOTO SYNC. RCVR INTERRUPT RESPONSE CODE
  471. ;    PAGE
  472.  
  473. ;
  474. ;    Initialize Hardware
  475. ;    Branch here for critical S/W errors or H/W reset
  476.  
  477. ;    Begin by reseting the 8250, 8253, and 8273
  478. INIT    EQU    $
  479.     DI            ; GATE INTERRUPTS
  480.     MVI    A,1        ; FIRST HALF OF 8273 RESET COMMAND
  481.     OUT    TEST73        ; ISSUE COMMAND
  482. ;  Book says to delay at least 10 tcycles then issue second half
  483.     XRA    A        ; A <-- 0              [ 4 tcy]
  484.     OUT    MCR        ; DROP 8250 DTR & RTS  [10 tcy]
  485.     OUT    IER        ; KILL 8250 INTERRUPTS [10 tcy]
  486. ;  This should be enough delay
  487.     OUT    TEST73        ; SECOND HALF OF 8273 RESET COMMAND
  488.     IN    RBR        ; FLUSH THE 8250 INPUT REGISTER
  489.     IN    RBR
  490.  
  491. ;    H/W is now in an acceptable state, continue
  492.     LXI    SP,STACK    ; SET STACK POINTER
  493.  
  494. ;    Now clear SRAM
  495.     LXI    D,HIRAM        ; DE <-- HIGH SRAM ADDRESS
  496.     LXI    H,LORAM        ; HL <-- LOW SRAM ADDRESS
  497.  
  498. INIT1    EQU    $
  499.     MVI    M,0        ; CLEAR NEXT LOCATION
  500.     INX    H        ; INCREMENT POINTER
  501.     MOV    A,D        ; A <-- MSB OF HIGH ADDRESS
  502.     CMP    H
  503.     JNZ    INIT1        ; IF (D <> H) GOTO INIT1
  504.     MOV    A,E        ; A <-- LSB OF HIGH ADDRESS
  505.     CMP    L
  506.     JNZ    INIT1        ; IF (E <> L) GOTO INIT1
  507.     MVI    M,0        ; ZERO LAST RAM LOCATION
  508.  
  509. ;    Initialize linked list of free cells
  510.     MVI    A,NCELL        ; A <-- # OF CELLS
  511.         STA    NLIST        ; SAVE IN SRAM
  512.     MOV    B,A        ; NOW MOVE CELL COUNT TO B
  513.     LXI    D,BAREA        ; DE <-- ADDRESS OF BUFFER AREA
  514.     DCR    B        ; SO THAT LAST CELL IS 0
  515. INIT2    EQU    $
  516.     LXI    H,128        ; HL <-- CELL SIZE
  517.     DAD    D        ; HL <-- ADDRESS OF NEXT CELL
  518.     XCHG            ; DE <-- NEXT, HL <-- CURRENT
  519.     MOV    M,E        ; CURRENT GETS LSB OF NEXT
  520.     INX    H
  521.     MOV    M,D        ; FOLLOWED BY MSB OF NEXT
  522.     DCR    B        ; B <-- B-1
  523.     JNZ    INIT2        ; IF (B <> 0) GOTO INIT2
  524.  
  525. ;    Initialize state variables
  526.     MVI    A,7
  527.     STA    AR$STA
  528.     MVI    A,0FFH
  529.     STA    AT$STA
  530.  
  531. ;    Initialize queue variables
  532.     LXI    H,AT$QT
  533.     SHLD    AT$QR
  534.     SHLD    AT$QW
  535.     LXI    H,ST$QT
  536.     SHLD    ST$QR
  537.     SHLD    ST$QW
  538.  
  539. ;    Initialize miscellaneous variables
  540.     LXI    H,0C002H    ; GENERAL RECEIVE COMMAND (8273)
  541.     SHLD    SRACT
  542.     LXI    H,330        ;*;; MAXIMUM ALLOWABLE PACKET LENGTH
  543.     SHLD    SRACT+2
  544.     LXI    H,0C802H    ; TRANSMIT FRAME COMMAND (8273)
  545.     SHLD    STACT
  546.     LXI    H,BAREA        ; H <-- ADDRESS OF FREE CELL AREA
  547.     SHLD    FL$HC        ; ESTABLISH FREE LIST HEAD CELL
  548.     LXI    H,MS10        ; H <-- CONSTANT FOR 10MS S/W TIMING
  549.     SHLD    TICKS        ; PRELOAD S/W COUNT VARIABLE
  550.     MVI    A,2        ; DEFAULT SQUELCH TAIL DELAY (20ms)
  551.     STA    TVAL
  552.     MVI    A,5        ; DEFAULT SLOT-TIME DELAY (50ms)
  553.     STA    SVAL
  554.     MVI    A,30        ; DEFAULT RELAY DELAY (300ms)
  555.     STA    RVAL
  556.     MVI    A,128        ; DEFAULT PERSISTENCE VALUE (0.5)
  557.     STA    PVAL
  558.  
  559. ;    Establish baud rate for asynchronous port
  560.     LXI    H,32        ; CONSTANT FOR 4800 BAUD
  561.     MVI    A,DLA        ; A <-- DIVISOR LATCH ACCESS FLAG
  562.     OUT    LCR        ; WRITE LINE CONTROL REGISTER
  563.     MOV    A,L        ; A <-- LSB OF BAUD RATE CONSTANT
  564.     OUT    DLL        ; WRITE DIVISOR LATCH LSB
  565.     MOV    A,H        ; A <-- MSB OF SAME
  566.     OUT    DLM        ; WRITE DIVISOR LATCH MSB
  567.     MVI    A,NP+D8+S2    ; NO PARITY, 8 DATA BITS, 2 STOP BITS
  568.     OUT    LCR        ; WRITE LINE CONTROL REGISTER
  569.  
  570. ;**********************************************************************
  571. ;    The following code segment is for VDS-1 users only!!!
  572. ;       Erase ';*;' in columns 1 thru 3 to assemble this segment.
  573. ;    Establish baud rate for synchronous port
  574.     MVI    A,C0+RLB+MD3+BIN ; 8253 MODE CONTROL WORD
  575.     OUT    ITCP        ; WRITE INTERVAL TIMER CONTROL PORT
  576.     LXI    H,SBR1200    ; CONSTANT FOR 1200 BAUD
  577.     MOV    A,L        ; A <-- LSB
  578.     OUT    PIT0        ; WRITE
  579.     MOV    A,H        ; A <-- MSB
  580.     OUT    PIT0        ; WRITE
  581.  
  582. ;    Activate the random number generator.
  583.     MVI    A,C2+RLB+MD3+BIN ; MODE CONTROL WORD
  584.     OUT    ITCP        ; WRITE
  585.     LXI    H,SEED        ; COUNTER VALUE
  586.     MOV    A,L        ; A <-- LSB
  587.     OUT    PIT2        ; WRITE
  588.     MOV    A,H        ; A <-- MSB
  589.     OUT    PIT2        ; WRITE
  590. ;**********************************************************************
  591.  
  592. ;    Asynchronous controller activation
  593. ;    RST5.5 to CPU is enabled first
  594.     MVI    A,ERI+ELI+EMI    ; RECEIVE AND LINE STATUS ENABLE
  595.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  596.     MVI    A,ADTR+ARTS+OUT1 ; DTR, RTS, & CD FOR HOST
  597.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  598.  
  599. ;    Synchronous controller activation follows
  600.     LXI    H,DTRANS
  601.     CALL    SCMDOT        ; SET DATA XFER MODE
  602.     LXI    H,OPMODE
  603.     CALL    SCMDOT        ; SET OPERATING MODE
  604.     LXI    H,SERIO
  605.     CALL    SCMDOT        ; SET SERIAL I/O MODE
  606.     LXI    H,SSDTR
  607.     CALL    SCMDOT        ; SET SYNCH. DTR TO MODEM
  608.     CALL    GCELL        ; GET A FREE CELL
  609.     XCHG            ; HL <-- CELL POINTER
  610.     SHLD    SR$BP        ; ESTABLISH NEW POINTERS
  611.     SHLD    SR$HC
  612.     MVI    M,0        ; RESET FORWARD POINTER
  613.     INX    H        ; ADVANCE POINTER
  614.     MVI    M,0
  615.     MVI    A,MSE        ; UNGATE RST5.5,RST6.5, & RST7.5
  616.     DB    30H        ; 8085 SIM INSTRUCTION
  617.     LXI    H,SRACT        ; SYNC. RECEIVER ACTIVATION COMMAND
  618.     CALL    SCMDOT
  619.  
  620. ;    LIGHTS! CAMERA! ACTION!
  621.     EI
  622. ;    PAGE
  623.  
  624. ;    TNC Executive Routine
  625.  
  626. EXEC    EQU    $
  627.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  628.     ANA    A
  629.     JNZ    EXEC2        ; IF (FLAGS SET) GOTO EXEC2
  630.     LDA    IT$FLG        ; A <-- TIMER CONTROL FLAG
  631.     ORA    A
  632.     JNZ    EXEC1        ; IF (TIMER ACTIVE) GOTO EXEC1
  633.     LXI    H,RPA        ; HL <-- READ PORT A COMMAND
  634.     CALL    SCMDOT        ; ISSUE COMMAND
  635.     CALL    SRSLIN        ; READ RESULTS
  636.     ANI    MCD        ; MASK MODEM CARRIER DETECT
  637.     JNZ    EXEC        ; IF (CHANNEL BUSY) GOTO EXEC
  638.     LDA    ST$QS        ; A <-- SYNC. XMTR QUEUE SIZE
  639.     ORA    A
  640.     JZ    EXEC        ; IF (EMPTY QUEUE) GOTO EXEC
  641.  
  642. ;**********************************************************************
  643. ;    The following code segment is for VDS-1 users only!!!
  644. ;       Remove ';*; in column 1 thru 3 to assemble this segment.
  645. ;  ASHBY and non-VDS VADCGs are rendered totally non-persistent
  646.     MVI    A,C2+RLL    ; READ CONTROL WORD
  647.     OUT    ITCP        ; WRITE INTERVAL TIMER CONTROL PORT
  648.     IN    PIT2        ; READ LSB OF TIMER (OUR RANDOM #)
  649.     MOV    B,A        ; COPY TO B FOR NOW
  650.     LDA    PVAL        ; A <-- PERSISTENCE VALUE
  651.     SUB    B
  652.     JNC    A5$S0A        ; IF (RANDOM < PVAL) GOTO A5$S0A
  653. ;**********************************************************************
  654.  
  655.     LDA    SVAL        ; A <-- SLOT-TIME VALUE
  656.     MOV    L,A        ; COPY TO L
  657.     XRA    A
  658.     MOV    H,A        ; EXTEND 16 BITS
  659.     SHLD    IT$VAL        ; ESTABLISH TIMER VALUE
  660.     STA    IT$STA        ; RECORD NEW STATE
  661.     INR    A
  662.     STA    IT$FLG        ; ACTIVATE TIMER
  663.     JMP    EXEC
  664.  
  665. ;    Active timer processing
  666. EXEC1    EQU    $
  667.     LHLD    TICKS        ; HL <-- S/W TIMER COUNT
  668.     DCX    H        ; DECREMENT
  669.     SHLD    TICKS        ; RECORD NEW COUNT
  670.     MOV    A,L        ; A <-- LSB OF COUNT
  671.     ORA    H        ; MSB
  672.     JNZ    EXEC        ; IF (NOT 0) GOTO EXEC
  673.     LXI    H,MS10        ; 10ms TIMER CONSTANT
  674.     SHLD    TICKS        ; RELOAD COUNT
  675.     LHLD    IT$VAL        ; HL <-- INTERVAL TIMER VALUE
  676.     DCX    H        ; DECREMENT TIMER
  677.     SHLD    IT$VAL        ; RECORD IT
  678.     MOV    A,L
  679.     ORA    H
  680.     JNZ    EXEC        ; IF (NOT EXPIRED) GOTO EXEC
  681.     STA    IT$FLG        ; DEACTIVATE TIMER
  682.     DI            ; GATE INTERRUPTS MOMENTARILY
  683.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  684.     ORI    EXTI        ; FLAG EXPIRED TIMER
  685.     STA    EA$FLG        ; RECORD FLAGS
  686.     EI            ; UNGATE
  687.     JMP    EXEC        ; BACK TO TOP
  688.  
  689. ;    End action processing
  690. EXEC2    EQU    $
  691.     RAR
  692.     JC    EX$A1        ; IF (SRFC) GOTO EX$A1
  693.     RAR
  694.     JC    EX$A2        ; IF (ARFC) GOTO EX$A2
  695.     RAR
  696.     JC    EX$A3        ; IF (STFC) GOTO EX$A3
  697.     RAR
  698.     JC    EX$A4        ; IF (ATFC) GOTO EX$A4
  699.     RAR
  700.     JC    EX$A5        ; IF (EXPIRED TIMER) GOTO EX$A5
  701.     RAR
  702.     JC    EX$A6        ; IF (SRDD) GOTO EX$A6
  703.     RAR
  704.     JC    EX$A7        ; IF (ARDD) GOTO EX$A7
  705.     JMP    EXEC        ; CONTINUE
  706.  
  707.  
  708.  
  709.  
  710.  
  711. ;    Here for synchronous receiver frame completion
  712. EX$A1    EQU    $
  713.     LHLD    SR$HC        ; HL <-- FRAME HEAD
  714.     PUSH    H        ; PRESERVE HL
  715.     DI            ; GATE INTERRUPTS MOMENTARILY
  716.     CALL    GCELL        ; GET A FREE CELL
  717.     EI            ; UNGATE
  718.     JZ    EX$A11        ; IF (BUFFERS FULL) GOTO EX$A11
  719.     XCHG            ; HL <-- CELL POINTER
  720.     SHLD    SR$BP        ; ESTABLISH NEW POINTERS
  721.     SHLD    SR$HC
  722.     MVI    M,0        ; RESET FORWARD POINTER
  723.     INX    H        ; ADVANCE POINTER
  724.     MVI    M,0
  725.     LXI    H,SRACT        ; HL <-- SYNC. RCVR ACTIVATION COMMAND
  726.     CALL    SCMDOT        ; ISSUE COMMAND
  727. EX$A11    EQU    $
  728.     MVI    B,0FFH-SRFC    ; B <-- FLAG MASK
  729.     DI            ; GATE INTERRUPTS MOMENTARILY
  730.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  731.     ANA    B        ; MASK OUT SRFC
  732.     STA    EA$FLG        ; WRITE FLAGS
  733.     EI            ; UNGATE
  734.     POP    H        ; RESTORE FRAME HEAD
  735.     LDA    SR$FR        ; A <-- FRAME RESULTS
  736.     CPI    0E0H        ; EXPECTED RESULTS
  737.     JNZ    EX$A12        ; IF (BAD FRAME) GOTO EX$A12
  738.     CALL    LATQ        ; ELSE LINK FRAME TO ASYNC. XMIT QUEUE
  739.     JMP    EXEC
  740. EX$A12    EQU    $
  741.     CALL    FCHN        ; RELEASE BAD FRAME
  742.     JMP    EXEC
  743.  
  744.  
  745.  
  746.  
  747.  
  748. ;    Here for asynchronous receiver frame completion
  749. EX$A2    EQU    $
  750.     MVI    B,0FFH-ARFC    ; B <-- FLAG MASK
  751.     DI            ; GATE INTERRUPTS MOMENTARILY
  752.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  753.     ANA    B        ; MASK OUT ARFC
  754.     STA    EA$FLG        ; WRITE FLAGS
  755.     EI            ; UNGATE
  756.     LHLD    AR$FS        ; HL <-- FRAME SIZE
  757.     MOV    B,H        ; COPY TO BC
  758.     MOV    C,L
  759.     LHLD    AR$FH        ; HL <-- FRAME HEAD
  760.     CALL    LSTQ        ; LINK FRAME TO SYNC. XMIT QUEUE
  761.     MVI    A,ADTR+ARTS+OUT1 ; DTR, RTS, AND CD FOR HOST
  762.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  763.     JMP    EXEC
  764.  
  765.  
  766.  
  767.  
  768.  
  769. ;    Here for synchronous transmitter frame completion
  770. EX$A3    EQU    $
  771.     MVI    B,0FFH-STFC    ; B <-- FLAG MASK
  772.     DI            ; GATE INTERRUPTS MOMENTARILY
  773.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  774.     ANA    B        ; MASK OUT STFC
  775.     STA    EA$FLG        ; WRITE FLAGS
  776.     EI            ; UNGATE
  777.     LDA    ST$QS        ; A <-- QUEUE SIZE
  778.     ORA    A
  779.     JZ    EX$A32        ; IF (EMPTY QUEUE) GOTO EX$A32
  780.     DCR    A        ; ELSE DECREMENT COUNT
  781.     STA    ST$QS        ; WRITE NEW COUNT
  782.     LHLD    ST$QR        ; HL <-- QUEUE READ POINTER
  783.     LXI    D,-ST$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  784.     PUSH    H
  785.     DAD    D
  786.     POP    H        ; RESTORE READ POINTER
  787.     JNC    EX$A31        ; IF (NOT BOTTOM) GOTO EX$A31
  788.     LXI    H,ST$QT        ; HL <-- QUEUE TOP ADDRESS
  789. EX$A31    EQU    $
  790.     MOV    C,M        ; LSB OF FRAME SIZE
  791.     INX    H        ; ADVANCE POINTER
  792.     MOV    B,M        ; MSB OF FRAME SIZE
  793.     INX    H
  794.     MOV    E,M        ; LSB OF FRAME HEAD
  795.     INX    H
  796.     MOV    D,M        ; MSB OF FRAME HEAD
  797.     INX    H
  798.     SHLD    ST$QR        ; RECORD NEW POINTER
  799.     XCHG            ; HL <-- FRAME HEAD
  800.     SHLD    ST$BP        ; RECORD IT
  801.     LXI    H,STACT+2    ; HL <-- SYNC. XMTR PARAMETER POINTER
  802.     MOV    M,C        ; COPY LSB OF FRAME SIZE
  803.     INX    H        ; ADVANCE POINTER
  804.     MOV    M,B        ; COPY MSB OF FRAME SIZE
  805.     LXI    H,STACT        ; HL <-- SYNC. XMTR ACTIVATION COMMAND
  806.     CALL    SCMDOT        ; ISSUE COMMAND
  807. ;  SET WATCHDOG TIMER HERE (LETS GO FOR A DEFAULT VALUE INITIALLY)
  808.     LXI    H,WDVAL        ; HL <-- DEFAULT WATCHDOG TIMER
  809.     SHLD    IT$VAL        ; RECORD IT
  810.     MVI    A,1
  811.     STA    IT$FLG        ; ENABLE TIMER
  812.     INR    A        ; NEW STATE
  813.     STA    IT$STA        ; RECORD IT
  814.     JMP    EXEC
  815. ;    Queue empty, disable synchronous transmitter (deactivate RTS)
  816. EX$A32    EQU    $
  817.     LXI    H,DARTS        ; HL <-- DEACTIVATE RTS COMMAND
  818.     CALL    SCMDOT        ; ISSUE COMMAND
  819.     LDA    TVAL        ; A <-- SQUELCH TAIL TIMER VALUE
  820.     MOV    L,A        ; COPY VALUE TO L
  821.     XRA    A
  822.     MOV    H,A        ; EXTEND 16 BITS
  823.     SHLD    IT$VAL        ; RECORD IT
  824.     INR    A        ; A <-- 1
  825.     STA    IT$FLG        ; ACTIVATE TIMER
  826.     MVI    A,3        ; NEW STATE
  827.     STA    IT$STA        ; RECORD IT
  828.     JMP    EXEC
  829.  
  830.  
  831.  
  832.  
  833.  
  834. ;    Here for asynchronous transmitter frame completion
  835. EX$A4    EQU    $
  836.     MVI    B,0FFH-ATFC    ; B <-- FLAG MASK
  837.     DI            ; GATE INTERRUPTS MOMENTARILY
  838.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  839.     ANA    B        ; MASK OUT ATFC
  840.     STA    EA$FLG        ; WRITE FLAGS
  841.     EI            ; UNGATE
  842.     LDA    AT$QS        ; A <-- QUEUE SIZE
  843.     ORA    A
  844.     JZ    EXEC        ; IF (EMPTY QUEUE) GOTO EXEC
  845.     DCR    A        ; ELSE DECREMENT COUNT
  846.     STA    AT$QS        ; WRITE NEW COUNT
  847.     LHLD    AT$QR        ; HL <-- QUEUE READ POINTER
  848.     LXI    D,-AT$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  849.     PUSH    H        ; PRESERVE HL
  850.     DAD    D
  851.     POP    H        ; RESTORE QUEUE POINTER
  852.     JNC    EX$A41        ; IF (NOT BOTTOM) GOTO EX$A41
  853.     LXI    H,AT$QT        ; HL <-- QUEUE TOP ADDRESS
  854. EX$A41    EQU    $
  855.     MOV    E,M        ; LSB OF FRAME HEAD
  856.     INX    H
  857.     MOV    D,M        ; MSB OF FRAME HEAD
  858.     INX    H
  859.     SHLD    AT$QR        ; RECORD NEW POINTER
  860.     XCHG            ; HL <-- FRAME HEAD
  861.     CALL    LATQ3        ; SEND FEND
  862.     JMP    EXEC
  863.  
  864.  
  865.  
  866.  
  867.  
  868. ;    Here for timer expiration
  869. EX$A5    EQU    $
  870.     MVI    B,0FFH-EXTI    ; B <-- FLAG MASK
  871.     DI            ; GATE INTERRUPTS MOMENTARILY
  872.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  873.     ANA    B        ; MASK OUT EXTI
  874.     STA    EA$FLG        ; WRITE FLAGS
  875.     EI            ; UNGATE
  876.     LDA    IT$STA        ; A <-- STATE OF INTERVAL TIMER
  877.     ORA    A
  878.     JZ    A5$S0        ; IF (SLOT-TIME DELAY) GOTO A5$S0
  879.     DCR    A
  880.     JZ    A5$S1        ; IF (RELAY DELAY) GOTO A5$S1
  881.     DCR    A
  882.     JZ    A5$S2        ; IF (WATCH DOG) GOTO A5$S2
  883.     DCR    A
  884.     JZ    A5$S3        ; IF (SQUELCH DELAY) GOTO A5$S3
  885.     JMP    EXEC        ; IGNORE INVALID STATES
  886.  
  887. ;    Slot-time is expired, if channel not busy, activate RTS
  888. A5$S0    EQU    $
  889.     LXI    H,RPA        ; HL <-- READ PORT A COMMAND
  890.     CALL    SCMDOT        ; ISSUE COMMAND
  891.     CALL    SRSLIN        ; READ RESULTS
  892.     ANI    MCD        ; MASK MODEM CARRIER DETECT
  893.     JNZ    EXEC        ; IF (CHANNEL BUSY) GOTO EXEC
  894. A5$S0A    EQU    $
  895.     LXI    H,SRDIS        ; HL <-- SYNC. RCVR DISABLE COMMAND
  896.     CALL    SCMDOT        ; ISSUE COMMAND
  897.     LXI    H,STRTS        ; HL <-- SYNC. XMTR RTS ENABLE COMMAND
  898.     CALL    SCMDOT        ; ISSUE COMMAND
  899.     LDA    RVAL        ; A <-- RELAY DELAY VALUE
  900.     MOV    L,A        ; COPY TO L
  901.     XRA    A
  902.     MOV    H,A        ; EXTEND 16 BITS
  903.     SHLD    IT$VAL        ; SET DELAY VALUE
  904.     INR    A        ; A <-- 1
  905.     STA    IT$FLG        ; ACTIVATE TIMER
  906.     STA    IT$STA        ; RECORD NEW STATE
  907.     LXI    H,ST$QS        ; HL <-- QUEUE SIZE POINTER
  908.     DCR    M        ; DECREMENT COUNT
  909.     LHLD    ST$QR        ; HL <-- QUEUE READ POINTER
  910.     LXI    D,-ST$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  911.     PUSH    H
  912.     DAD    D
  913.     POP    H
  914.     JNC    A5$S0B        ; IF (NOT BOTTOM) GOTO A5$S0B
  915.     LXI    H,ST$QT        ; HL <-- QUEUE TOP ADDRESS
  916. A5$S0B    EQU    $
  917.     MOV    A,M        ; LSB OF FRAME SIZE
  918.     STA    STACT+2
  919.     INX    H        ; ADVANCE POINTER
  920.     MOV    A,M        ; MSB OF FRAME SIZE
  921.     STA    STACT+3
  922.     INX    H
  923.     MOV    E,M        ; LSB OF FRAME HEAD
  924.     INX    H
  925.     MOV    D,M        ; MSB OF FRAME HEAD
  926.     INX    H
  927.     SHLD    ST$QR        ; WRITE NEW POINTER
  928.     XCHG
  929.     SHLD    ST$BP        ; ESTABLISH NEW FRAME POINTER
  930.     JMP    EXEC
  931.  
  932. ;    Relay delay time expired, start data transmission
  933. A5$S1    EQU    $
  934.     LXI    H,STACT        ; HL <-- SYNC. XMTR ACTIVATION COMMAND
  935.     CALL    SCMDOT        ; ISSUE COMMAND
  936.     LXI    H,WDVAL        ; HL <-- WATCHDOG TIMER VALUE
  937.     SHLD    IT$VAL        ; RECORD IT
  938.     MVI    A,1
  939.     STA    IT$FLG        ; ACTIVATE TIMER
  940.     INR    A        ; NEW STATE
  941.     STA    IT$STA        ; RECORD IT
  942.     JMP    EXEC
  943.  
  944. ;    Watchdog timer expiration, kill the transmitter
  945. A5$S2    EQU    $
  946.     LXI    H,DARTS        ; HL <-- DEACTIVATE RTS COMMAND
  947.     CALL    SCMDOT        ; ISSUE COMMAND
  948.     JMP    INIT
  949.  
  950. ;    Squelch delay time expired, re-activate the sync. receiver
  951. A5$S3    EQU    $
  952.     LXI    H,SRACT        ; HL <-- SYNC. RCVR ACTIVATION COMMAND
  953.     CALL    SCMDOT        ; ISSUE COMMAND
  954.     JMP    EXEC
  955.  
  956.  
  957.  
  958.  
  959.  
  960. ;    Here when synchronous receiver is discarding a frame
  961. ;    because there are no available free cells.
  962. EX$A6    EQU    $
  963.     MVI    B,0FFH-SRDD    ; B <-- FLAG MASK
  964.     DI            ; GATE INTERRUPTS MOMENTARILY
  965.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  966.     ANA    B        ; MASK OUT SRDD
  967.     STA    EA$FLG        ; WRITE FLAGS
  968.     EI            ; UNGATE
  969.     LHLD    SR$HC        ; HL <-- FRAME HEAD
  970.     CALL    FCHN        ; FREE THIS CHAIN
  971.     LXI    H,SRDIS        ; HL <-- SYNC. RCVR DISABLE COMMAND
  972.     CALL    SCMDOT        ; ISSUE COMMAND
  973.     DI            ; GATE INTERRUPTS MOMENTARILY
  974.     CALL    GCELL        ; GET A FREE CELL
  975.     EI            ; UNGATE
  976.     XCHG            ; HL <-- CELL POINTER
  977.     SHLD    SR$BP        ; ESTABLISH NEW BUFFER POINTERS
  978.     SHLD    SR$HC
  979.     MVI    M,0        ; RESET FORWARD POINTER
  980.     INX    H        ; ADVANCE POINTER
  981.     MVI    M,0
  982.     LXI    H,SRACT        ; HL <-- SYNC. RCVR ACTIVATION COMMAND
  983.     CALL    SCMDOT        ; ISSUE COMMAND
  984.     XRA    A        ; NEW STATE (RECORDING DATA)
  985.     STA    SR$STA        ; RECORD IT
  986.     JMP    EXEC
  987.  
  988.  
  989.  
  990.  
  991.  
  992. ;    Here when asynchronous receiver is discarding a frame
  993. ;    because there are no available free cells.
  994. EX$A7    EQU    $
  995.     MVI    B,0FFH-ARDD    ; B <-- FLAG MASK
  996.     DI            ; GATE INTERRUPTS MOMENTARILY
  997.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  998.     ANA    B        ; MASK OUT ARDD
  999.     STA    EA$FLG        ; WRITE FLAGS
  1000.     EI            ; UNGATE
  1001.     LHLD    AR$HC        ; HL <-- FRAME HEAD
  1002.     CALL    FCHN        ; FREE THIS CHAIN
  1003.     MVI    A,ADTR+ARTS+OUT1 ; DTR, RTS, AND CD FOR HOST
  1004.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  1005.     JMP    EXEC
  1006. ;    PAGE
  1007.  
  1008. ;    Queue management routines for synchronous & asynchronous output
  1009.  
  1010. ;    Link a frame to the synchronous transmit queue
  1011. LSTQ    EQU    $
  1012.     XCHG            ; DE <-- ADDRESS OF FRAME
  1013.     LHLD    ST$QW        ; HL <-- QUEUE WRITE POINTER
  1014.     MOV    M,C        ; LSB OF FRAME SIZE
  1015.     INX    H        ; ADVANCE POINTER
  1016.     MOV    M,B        ; MSB OF FRAME SIZE
  1017.     INX    H
  1018.     MOV    M,E        ; LSB OF FRAME HEAD
  1019.     INX    H
  1020.     MOV    M,D        ; MSB OF FRAME HEAD
  1021.     INX    H        ; HL <-- NEXT QUEUE ENTRY
  1022.     LXI    D,-ST$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  1023.     PUSH    H        ; PRESERVE HL
  1024.     DAD    D
  1025.     POP    H        ; RESTORE QUEUE POINTER
  1026.     JNC    LSTQ1        ; IF (NOT BOTTOM) GOTO LSTQ1
  1027.     LXI    H,ST$QT        ; HL <-- QUEUE TOP ADDRESS
  1028. LSTQ1    EQU    $
  1029.     SHLD    ST$QW        ; WRITE NEW QUEUE POINTER
  1030.     LXI    H,ST$QS        ; HL <-- QUEUE SIZE POINTER
  1031.     INR    M        ; INCREMENT QUEUE SIZE
  1032.     RET
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038. ;    Link a frame to the asynchronous transmit queue
  1039. LATQ    EQU    $
  1040.     LDA    AT$QS        ; A <-- QUEUE SIZE
  1041.     ORA    A
  1042.     JNZ    LATQ1        ; IF (QUEUED FRAMES) GOTO LATQ1
  1043.     LDA    AT$STA        ; A <-- STATE OF ASYNC. TRANSMITTER
  1044.     CPI    0FFH
  1045.     JZ    LATQ3        ; IF (XMTR INACTIVE) GOTO LATQ3
  1046. LATQ1    EQU    $
  1047.     XCHG            ; DE <-- ADDRESS OF FRAME
  1048.     LHLD    AT$QW        ; HL <-- QUEUE WRITE POINTER
  1049.     MOV    M,E        ; LSB OF FRAME HEAD
  1050.     INX    H        ; ADVANCE POINTER
  1051.     MOV    M,D        ; MSB OF FRAME HEAD
  1052.     INX    H        ; HL <-- NEXT QUEUE ENTRY
  1053.     LXI    D,-AT$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  1054.     PUSH    H        ; PRESERVE HL
  1055.     DAD    D
  1056.     POP    H        ; RESTORE QUEUE POINTER
  1057.     JNC    LATQ2        ; IF (NOT BOTTOM) GOTO LATQ2
  1058.     LXI    H,AT$QT        ; HL <-- QUEUE TOP ADDRESS
  1059. LATQ2    EQU    $
  1060.     SHLD    AT$QW        ; WRITE NEW POINTER
  1061.     LXI    H,AT$QS        ; HL <-- QUEUE SIZE POINTER
  1062.     INR    M        ; INCREMENT QUEUE SIZE
  1063.     RET
  1064. ;    Queue is empty and asynchronous transmitter is
  1065. ;    inactive.  Don't queue this entry, just send it out.
  1066. LATQ3    EQU    $
  1067.     SHLD    AT$BP        ; ESTABLISH NEW POINTER
  1068.     MVI    A,FEND        ; A <-- FEND
  1069.     OUT    THR        ; WRITE TRANSMIT HOLDING REGISTER
  1070.     MVI    A,4        ; NEW STATE (OPENING FRAME)
  1071.     STA    AT$STA        ; RECORD IT
  1072.     MVI    A,ERI+ETI+ELI+EMI ; 8250 INTERRUPT ENABLE FLAGS
  1073.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1074.     RET
  1075. ;    PAGE
  1076.  
  1077. ;    Buffer management routines
  1078.  
  1079. ;    Allocate a free cell
  1080. GCELL    EQU    $
  1081.     LHLD    FL$HC        ; HL <-- HEAD CELL ON FREE LIST
  1082.     MOV    A,H        ; MSB OF ADDRESS
  1083.     ORA    L        ; LSB OF ADDRESS
  1084.     JZ    GC$EL        ; IF (EMPTY LIST) GOTO GC$EL
  1085.     XCHG            ; DE <-- FREE CELL
  1086.     LXI    H,FL$HC        ; HL <-- HEAD CELL POINTER
  1087.     LDAX    D        ; A <-- LSB OF NEXT FREE CELL
  1088.     MOV    M,A        ; COPY TO FL$HC
  1089.     INX    D        ; ADVANCE POINTERS
  1090.     INX    H
  1091.     LDAX    D        ; A <-- MSB OF NEXT FREE CELL
  1092.     MOV    M,A        ; COPY TO FL$HC
  1093.     DCX    D        ; RESET FREE CELL POINTER
  1094. GC$EL    EQU    $
  1095.     RET
  1096.  
  1097. ;    Attach a cell to the free list
  1098. FCELL    EQU    $
  1099.     LXI    H,FL$HC        ; HL <-- HEAD CELL POINTER
  1100.     MOV    C,M        ; C <-- LSB OF FIRST CELL
  1101.     MOV    M,E        ; UPDATE LSB OF FL$HC
  1102.     INX    H        ; ADVANCE POINTER
  1103.     MOV    B,M        ; B <-- MSB OF FIRST CELL
  1104.     MOV    M,D        ; UPDATE MSB OF FL$HC
  1105.     XCHG            ; HL <-- RELEASED CELL
  1106.     MOV    E,M        ; E <-- LSB OF NEXT CELL
  1107.     MOV    M,C        ; COPY LSB OF OLD HC TO NEW
  1108.     INX    H        ; ADVANCE POINTER
  1109.     MOV    D,M        ; D <-- MSB OF NEXT CELL
  1110.     MOV    M,B        ; COPY MSB OF OLD HC TO NEW
  1111.     INX    H        ; ADVANCE POINTER
  1112.     MVI    M,0        ; RESET NBYTE
  1113.     INX    H
  1114.     MVI    M,0        ; RESET NREAD
  1115.     XCHG            ; HL <-- NEXT CELL IN CHAIN
  1116.     RET
  1117.  
  1118. ;    Attach a chain of cells to the free list
  1119. FCHN    EQU    $
  1120.     XCHG            ; DE <-- CELL TO BE RELEASED
  1121.     DI            ; GATE INTERRUPTS MOMENTARILY
  1122.     CALL    FCELL        ; FREE IT UP
  1123.     EI            ; UNGATE
  1124.     MOV    A,H        ; MSB OF FORWARD POINTER FROM CELL
  1125.     ORA    L        ; LSB OF SAME
  1126.     JNZ    FCHN        ; IF (MORE CELLS) GOTO FCHN
  1127.     RET
  1128. ;    PAGE
  1129.  
  1130. ;    Extract a character from the buffer referenced by HL
  1131. GCHAR    EQU    $
  1132.     PUSH    H        ; PRESERVE HL
  1133.     INX    H        ; SKIP FORWARD POINTER
  1134.     INX    H
  1135.     MOV    A,M        ; A <-- NBYTES
  1136.     INX    H        ; ADVANCE POINTER
  1137.     SUB    M        ; CHECK NREAD
  1138.     JZ    GC$BE        ; IF (BUFFER EXHAUSTED) GOTO GC$BE
  1139.     PUSH    D        ; PRESERVE DE
  1140.     INR    M        ; INCREMENT NREAD
  1141.     MOV    E,M        ; E <-- NREAD
  1142.     XRA    A
  1143.     MOV    D,A        ; EXTEND 16 BITS
  1144.     DAD    D        ; HL <-- HL + DE
  1145.     INR    A        ; RESET 'Z' FLAG
  1146.     MOV    A,M        ; A <-- CHARACTER
  1147.     POP    D        ; RESTORE DE
  1148.     POP    H        ; RESTORE HL
  1149.     RET
  1150. ;    Follow chain to next buffer
  1151. GC$BE    EQU    $
  1152.     POP    H        ; RESTORE HL
  1153.     PUSH    D        ; PRESERVE DE & BC
  1154.     PUSH    B
  1155.     XCHG            ; DE <-- BUFFER POINTER
  1156.     CALL    FCELL        ; RELEASE THIS CELL
  1157.     POP    B        ; RESTORE BC & DE
  1158.     POP    D
  1159.     MOV    A,H        ; MSB OF NEXT CELL IN CHAIN
  1160.     ORA    L        ; LSB OF SAME
  1161.     JNZ    GCHAR        ; IF (GOOD BUFFER) GOTO GCHAR
  1162.     RET            ; ELSE RETURN WITH 'Z' FLAG SET
  1163.  
  1164. ;    Stuff a character into the buffer referenced by HL
  1165. PCHAR    EQU    $
  1166.     PUSH    D        ; PRESERVE DE
  1167.     PUSH    PSW        ; PRESERVE PSW (CHARACTER)
  1168.     INX    H        ; SKIP FORWARD POINTER
  1169.     INX    H
  1170.     MVI    A,124        ; A <-- BUFFER LIMIT
  1171.     SUB    M        ; A <-- 124 - NBYTES
  1172.     CZ    PC$NB        ; IF (NEED BUFFER) CALL PC$NB
  1173.     PUSH    H        ; PRESERVE HL (BUFFER POINTER)
  1174.     INR    M        ; INCREMENT NBYTES
  1175.     MOV    E,M        ; E <-- NBYTES
  1176.     XRA    A
  1177.     MOV    D,A        ; EXTEND 16 BITS
  1178.     INX    H        ; SKIP NBYTES
  1179.     DAD    D        ; HL <-- HL + DE
  1180.     POP    D        ; RESTORE POINTER
  1181.     POP    PSW        ; RESTORE CHARACTER
  1182.     MOV    M,A        ; COPY CHARACTER TO BUFFER
  1183.     XCHG            ; HL <-- ORIGINAL POINTER
  1184.     DCX    H        ; ADJUST POINTER
  1185.     DCX    H
  1186.     POP    D        ; RESTORE DE
  1187.     XRA    A
  1188.     INR    A        ; RESET 'Z' FLAG
  1189.     RET
  1190. ;    Here if PCHAR needs a new buffer
  1191. PC$NB    EQU    $
  1192.     PUSH    H        ; PRESERVE HL
  1193.     CALL    GCELL        ; FREE CELL POINTER TO DE
  1194.     POP    H        ; RESTORE HL
  1195.     JZ    PC$BF        ; IF (BUFFERS FULL) GOTO PC$BF
  1196.     DCX    H
  1197.     MOV    M,D        ; COPY MSB TO PREVIOUS CELL
  1198.     DCX    H        ; ADVANCE POINTER
  1199.     MOV    M,E        ; COPY LSB TO PREVIOUS CELL
  1200.     XCHG            ; HL <-- NEW BUFFER POINTER
  1201.     MVI    M,0        ; RESET FORWARD POINTER
  1202.     INX    H        ; ADVANCE POINTER
  1203.     MVI    M,0
  1204.     INX    H
  1205.     RET
  1206. ;    Here if free cell not available
  1207. PC$BF    EQU    $
  1208.     POP    PSW        ; PURGE RETURN ADDRESS FROM STACK
  1209.     POP    PSW        ; RESTORE CHARACTER
  1210.     POP    D        ; RESTORE DE
  1211.     XRA    A        ; SET 'Z' FLAG
  1212.     RET
  1213. ;    PAGE
  1214.  
  1215. ;    Asynchronous Interrupt Response Code
  1216.  
  1217. AIRC    EQU    $
  1218.     PUSH    PSW        ; SAVE PROGRAM STATUS WORD
  1219.     IN    IIR        ; READ INTERRUPT IDENTIFICATION REG.
  1220.     RAR            ; RIGHT JUSTIFY ID BITS
  1221.     ANI    00000011B    ; MASK
  1222.     JZ    IRC$AM        ; IF (MODEM STATUS) GOTO IRC$AM
  1223.     DCR    A
  1224.     JZ    IRC$AT        ; IF (XMTR EMPTY) GOTO IRC$AT
  1225.     DCR    A
  1226.     JZ    IRC$AR        ; IF (DATA READY) GOTO IRC$AR
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232. ;    Here for line status interrupt
  1233. IRC$AL    EQU    $
  1234.     IN    LSR        ; READ LINE STATUS REGISTER
  1235.     ANI    BI        ; MASK BREAK INTERRUPT
  1236. ;    Treat overrun, parity, framing errors as data ready
  1237.     JZ    IRC$AR        ; IF (NOT BI) GOTO IRC$AR
  1238.     IN    RBR        ; FLUSH NULL FROM BUFFER
  1239.     POP    PSW        ; RESTORE PSW
  1240.     EI            ; UNGATE
  1241.     RET            ; RETURN FROM INTERRUPT
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247. ;    Here for modem status interrupt
  1248. IRC$AM    EQU    $
  1249.     IN    MSR        ; READ MODEM STATUS
  1250.     PUSH    PSW        ; SAVE STATUS
  1251.     ANI    DCTS+DDSR    ; MASK SOURCE BITS OF INTEREST
  1252.     RAR
  1253.     RAR
  1254.     JM    AM$1        ; IF (DELTA CTS) GOTO AM$1
  1255.     JC    INIT        ; IF (HOST LOST) GOTO INIT
  1256. ;    Ignore other sources of this interrupt
  1257.     POP    PSW        ; REMOVE STATUS FROM STACK
  1258.     POP    PSW
  1259.     EI
  1260.     RET            ; RETURN FROM INTERRUPT
  1261. ;    Here if Clear-To-Send has changed state
  1262. AM$1    EQU    $
  1263.     POP    PSW        ; FETCH MODEM STATUS FROM STACK
  1264.     ANI    TCTS        ; MASK TERMINAL CLEAR-TO-SEND STATUS
  1265.     JNZ    AM$2        ; IF (CLEAR-TO-SEND) GOTO AM$2
  1266. ;    Host has full buffer or something, stop sending
  1267.     MVI    A,ERI+ELI+EMI    ; INTERRUPT ENABLE FLAGS
  1268.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1269.     POP    PSW
  1270.     EI
  1271.     RET            ; RETURN FROM INTERRUPT
  1272. ;    Host is now ready to receive data again
  1273. AM$2    EQU    $
  1274.     LDA    AT$STA        ; A <-- STATE OF TRANSMITTER
  1275.     CPI    0FFH
  1276.     JZ    AM$3        ; IF (INACTIVE) GOTO AM$3
  1277.     MVI    A,ERI+ETI+ELI+EMI ; INTERRUPT ENABLE FLAGS
  1278.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1279. AM$3    EQU    $
  1280.     POP    PSW
  1281.     EI
  1282.     RET            ; RETURN FROM INTERRUPT
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288. ;    Here for asynchronous transmit interrupt
  1289. IRC$AT    EQU    $
  1290.     LDA    AT$STA        ; A <-- STATE OF TRANSMITTER
  1291.     ORA    A
  1292.     JZ    AT$S0        ; IF (NOT ESCAPED) GOTO AT$S0
  1293.     DCR    A
  1294.     JZ    AT$S1        ; IF (SENDING TFESC) GOTO AT$S1
  1295.     DCR    A
  1296.     JZ    AT$S2        ; IF (SENDING TFEND) GOTO AT$S2
  1297.     DCR    A
  1298.     JZ    AT$S3        ; IF (END OF FRAME) GOTO AT$S3
  1299.     DCR    A
  1300.     JZ    AT$S4        ; IF (OPENING FRAME) GOTO AT$S4
  1301.     DCR    A
  1302.     JZ    AT$S5        ; IF (OPENING FRAME II) GOTO AT$S5
  1303.     JMP    RST1+1        ; IGNORE INACTIVE STATE
  1304.  
  1305. ;    Here for normal data transmission (not currently escaped)
  1306. AT$S0    EQU    $
  1307.     PUSH    H        ; PRESERVE HL
  1308.     LHLD    AT$BP        ; HL <-- BUFFER POINTER
  1309.     CALL    GCHAR        ; MOVE NEXT CHARACTER TO A
  1310.     SHLD    AT$BP        ; SAVE UPDATED POINTER
  1311.     POP    H        ; RESTORE HL
  1312.     JZ    AT$S0S3        ; IF (END OF FRAME) GOTO AT$S0S3
  1313.     CPI    FESC
  1314.     JZ    AT$S0S1        ; IF (CHAR = FESC) GOTO AT$S0S1
  1315.     CPI    FEND
  1316.     JZ    AT$S0S2        ; IF (CHAR = FEND) GOTO AT$S0S2
  1317.     OUT    THR        ; WRITE CHARACTER
  1318.     POP    PSW
  1319.     EI
  1320.     RET            ; RETURN FROM INTERRUPT
  1321. ;    Send FESC and change state to 1
  1322. AT$S0S1    EQU    $
  1323.     OUT    THR        ; WRITE FESC
  1324.     MVI    A,1        ; NEW STATE
  1325.     STA    AT$STA        ; RECORD NEW STATE
  1326.     POP    PSW
  1327.     EI
  1328.     RET            ; RETURN FROM INTERRUPT
  1329. ;    Send FESC and change state to 2
  1330. AT$S0S2    EQU    $
  1331.     MVI    A,FESC        ; A <-- FESC
  1332.     OUT    THR        ; WRITE
  1333.     MVI    A,2        ; NEW STATE
  1334.     STA    AT$STA        ; RECORD NEW STATE
  1335.     POP    PSW
  1336.     EI
  1337.     RET            ; RETURN FROM INTERRUPT
  1338. ;    Send FEND and change state to 3
  1339. AT$S0S3    EQU    $
  1340.     MVI    A,FEND        ; A <-- FEND
  1341.     OUT    THR        ; WRITE
  1342.     MVI    A,3        ; NEW STATE
  1343.     STA    AT$STA        ; RECORD NEW STATE
  1344.     POP    PSW
  1345.     EI
  1346.     RET            ; RETURN FROM INTERRUPT
  1347.  
  1348. ;    Send TFESC (FESC was last character sent)
  1349. AT$S1    EQU    $
  1350.     MVI    A,TFESC        ; A <-- TFESC
  1351.     OUT    THR        ; WRITE
  1352.     XRA    A        ; NEW STATE (NOT ESCAPED)
  1353.     STA    AT$STA        ; RECORD NEW STATE
  1354.     POP    PSW
  1355.     EI
  1356.     RET            ; RETURN FROM INTERRUPT
  1357.  
  1358. ;    Send TFEND (FESC was last character sent)
  1359. AT$S2    EQU    $
  1360.     MVI    A,TFEND        ; A <-- TFEND
  1361.     OUT    THR        ; WRITE
  1362.     XRA    A        ; NEW STATE (NOT ESCAPED)
  1363.     STA    AT$STA        ; RECORD NEW STATE
  1364.     POP    PSW
  1365.     EI
  1366.     RET            ; RETURN FROM INTERRUPT
  1367.  
  1368. ;    Here for end of frame transmission - FEND already sent
  1369. AT$S3    EQU    $
  1370.     MVI    A,ERI+ELI+EMI    ; RCVR, LINE, AND MODEM ENABLE FLAGS
  1371.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1372.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1373.     ORI    ATFC        ; SET ASYNC. XMTR FRAME COMPLETE
  1374.     STA    EA$FLG        ; WRITE FLAGS
  1375.     MVI    A,0FFH        ; NEW STATE (ASYNC. XMTR DISABLED)
  1376.     STA    AT$STA        ; RECORD IT
  1377.     POP    PSW
  1378.     EI
  1379.     RET
  1380.  
  1381. ;    Here for opening frame, send frame begin / end byte
  1382. AT$S4    EQU    $
  1383.     MVI    A,FEND
  1384.     OUT    THR        ; WRITE CONTROL BYTE
  1385.     MVI    A,5        ; NEXT STATE = 5
  1386.     STA    AT$STA        ; ALSO IS OUR NEW STATE
  1387.     POP    PSW
  1388.     EI
  1389.     RET
  1390.  
  1391. ;    Next for opening frame, send data frame control byte
  1392. AT$S5    EQU    $
  1393.     XRA    A        ; A <-- 0
  1394.     OUT    THR        ; WRITE CONTROL BYTE
  1395.     STA    AT$STA        ; ALSO IS OUR NEW STATE
  1396.     POP    PSW
  1397.     EI
  1398.     RET
  1399.  
  1400.  
  1401.  
  1402.  
  1403. ;    Here for asynchronous receive interrupt
  1404. IRC$AR    EQU    $
  1405.     LDA    AR$STA        ; A <-- STATE OF RECEIVER
  1406.     ORA    A
  1407.     JZ    AR$S0        ; IF (EXPECTING DATA) GOTO AR$S0
  1408.     DCR    A
  1409.     JZ    AR$S1        ; IF (ESCAPED) GOTO AR$S1
  1410.     DCR    A
  1411.     JZ    AR$S2        ; IF (EXPECTING COMMAND) GOTO AR$S2
  1412.     DCR    A
  1413.     JZ    AR$S3        ; IF (EXPECTING P-VALUE) GOTO AR$S3
  1414.     DCR    A
  1415.     JZ    AR$S4        ; IF (EXPECTING S-VALUE) GOTO AR$S4
  1416.     DCR    A
  1417.     JZ    AR$S5        ; IF (EXPECTING T-VALUE) GOTO AR$S5
  1418.     DCR    A
  1419.     JZ    AR$S6        ; IF (EXPECTING TXDELAY) GOTO AR$S6
  1420.  
  1421. ;    Here if waiting for FEND to begin a new frame
  1422. AR$S7    EQU    $
  1423.     IN    RBR        ; READ CHARACTER
  1424.     CPI    FEND
  1425.     JNZ    RST1+1        ; IF (NOT FEND) RETURN FROM INTERRUPT
  1426.     MVI    A,2        ; NEW STATE
  1427.     STA    AR$STA        ; RECORD NEW STATE
  1428.     POP    PSW
  1429.     EI
  1430.     RET            ; RETURN FROM INTERRUPT
  1431.  
  1432. ;    Here if expecting frame data
  1433. AR$S0    EQU    $
  1434.     IN    RBR        ; READ CHARACTER
  1435.     CPI    FESC
  1436.     JZ    AR$S0S1        ; IF (DATA = FESC) GOTO AR$S0S1
  1437.     CPI    FEND
  1438.     JZ    AR$S0S2        ; IF (DATA = FEND) GOTO AR$S0S2
  1439.     PUSH    H        ; PRESERVE HL
  1440.     LHLD    AR$BP        ; HL <-- BUFFER POINTER
  1441.     CALL    PCHAR        ; STORE CHARACTER
  1442.     JZ    AR$S0S7        ; IF (BUFFERS FULL) GOTO AR$S0A
  1443.     SHLD    AR$BP        ; RECORD NEW POINTER
  1444.     LHLD    AR$FSZ        ; HL <-- FRAME SIZE
  1445.     INX    H        ; INCREMENT COUNT
  1446.     SHLD    AR$FSZ        ; RECORD IT
  1447.     POP    H        ; RESTORE HL
  1448.     POP    PSW
  1449.     EI
  1450.     RET            ; RETURN FROM INTERRUPT
  1451. ;    Here we deal with a serious problem.  We are in the middle
  1452. ;    of a frame and filled our current buffer, but alas, there
  1453. ;    are no free cells to allocate.  Return all buffers in this
  1454. ;    frame to the free cell list and hope we recover.
  1455. AR$S0S7    EQU    $
  1456. AR$S1S7    EQU    $
  1457.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1458.     ORI    ARDD        ; ASYNC. RECEIVER DISCARDING DATA
  1459.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1460.     MVI    A,ADTR+OUT1    ; DTR & CD, NO RTS
  1461.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  1462.     POP    H        ; RESTORE HL
  1463. ;    Here we just change state to wait for the next incoming
  1464. ;    frame and hope by then that we have recovered some cells.
  1465. AR$S2S7    EQU    $
  1466.     MVI    A,7        ; NEW STATE
  1467.     STA    AR$STA        ; RECORD NEW STATE
  1468.     POP    PSW
  1469.     EI
  1470.     RET            ; RETURN FROM INTERRUPT
  1471. ;    FESC was just detected. Change state to 1 and see what follows.
  1472. AR$S0S1    EQU    $
  1473.     MVI    A,1        ; NEW STATE
  1474.     STA    AR$STA        ; RECORD IT
  1475.     POP    PSW
  1476.     EI
  1477.     RET            ; RETURN FROM INTERRUPT
  1478. ;    FEND was just detected.  Move frame to synch. transmit queue.
  1479. AR$S0S2    EQU    $
  1480.     PUSH    H        ; PRESERVE HL
  1481.     LHLD    AR$HC        ; HL <-- HEAD CELL POINTER
  1482.     SHLD    AR$FH        ; SAVE POINTER FOR EXEC
  1483.     LHLD    AR$FSZ        ; HL <-- FRAME SIZE
  1484.     SHLD    AR$FS        ; SAVE FOR EXECUTIVE
  1485.     MVI    A,2        ; NEW STATE
  1486.     STA    AR$STA        ; RECORD IT
  1487.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1488.     ORI    ARFC        ; ASYNC. RECEIVER FRAME COMPLETE
  1489.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1490.     MVI    A,ADTR+OUT1    ; DTR & CD, NO RTS
  1491.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  1492.     POP    H        ; RESTORE HL
  1493.     POP    PSW
  1494.     EI
  1495.     RET            ; RETURN FROM INTERRUPT
  1496.  
  1497. ;    This character follows an FESC, must be TFESC or TFEND
  1498. AR$S1    EQU    $
  1499.     XRA    A        ; NEW STATE
  1500.     STA    AR$STA        ; RECORD IT
  1501.     IN    RBR        ; READ CHARACTER
  1502.     CPI    TFESC
  1503.     JZ    AR$S1A        ; IF (DATA = TFESC) GOTO AR$S1A
  1504.     CPI    TFEND
  1505.     JNZ    RST1+1        ; IF (DATA <> TFEND) RETURN FROM INT.
  1506. ;    Character was TFEND.  Translate it.
  1507.     MVI    A,FEND        ; A <-- FEND
  1508.     JMP    AR$S1B        ; STORE IT
  1509. ;    Character was TFESC.  Translate it.
  1510. AR$S1A    EQU    $
  1511.     MVI    A,FESC        ; A <-- FESC
  1512. AR$S1B    EQU    $
  1513.     PUSH    H        ; PRESERVE HL
  1514.     LHLD    AR$BP        ; HL <-- BUFFER POINTER
  1515.     CALL    PCHAR        ; STORE CHARACTER
  1516.     JZ    AR$S1S7        ; IF (BUFFERS FULL) GOTO AR$S1S7
  1517.     SHLD    AR$BP        ; RECORD NEW POINTER
  1518.     LHLD    AR$FSZ        ; HL <-- FRAME SIZE
  1519.     INX    H        ; INCREMENT COUNT
  1520.     SHLD    AR$FSZ        ; RECORD IT
  1521.     POP    H        ; RESTORE HL
  1522.     POP    PSW
  1523.     EI
  1524.     RET            ; RETURN FROM INTERRUPT
  1525.  
  1526. ;    Last character seen was FEND.  Look for frame command.
  1527. AR$S2    EQU    $
  1528.     IN    RBR        ; READ CHARACTER
  1529.     CPI    FEND
  1530.     JZ    RST1+1        ; RETURN FROM INTERRUPT
  1531.     ORA    A
  1532.     JZ    AR$S2S0        ; IF (DATA FRAME) GOTO AR$S2S0
  1533.     DCR    A
  1534.     JZ    AR$S2A        ; IF (R COMMAND) GOTO AR$S2A
  1535.     DCR    A
  1536.     JZ    AR$S2B        ; IF (P COMMAND) GOTO AR$S2B
  1537.     DCR    A
  1538.     JZ    AR$S2C        ; IF (S COMMAND) GOTO AR$S2C
  1539.     DCR    A
  1540.     JZ    AR$S2D        ; IF (T COMMAND) GOTO AR$S2D
  1541.     JMP    AR$S2S7        ; BOGUS COMMAND, WAIT FOR FEND
  1542. ;    Here if TxDelay value to follow
  1543. AR$S2A    EQU    $
  1544.     MVI    A,6        ; NEW STATE
  1545.     STA    AR$STA        ; RECORD IT
  1546.     POP    PSW
  1547.     EI
  1548.     RET            ; RETURN FROM INTERRUPT
  1549. ;    Here if Persistence value to follow
  1550. AR$S2B    EQU    $
  1551.     MVI    A,3
  1552.     STA    AR$STA    
  1553.     POP    PSW
  1554.     EI
  1555.     RET
  1556. ;    Here if Slot-time value to follow
  1557. AR$S2C    EQU    $
  1558.     MVI    A,4
  1559.     STA    AR$STA    
  1560.     POP    PSW
  1561.     EI
  1562.     RET
  1563. ;    Here if Squelch-delay value to follow
  1564. AR$S2D    EQU    $
  1565.     MVI    A,5
  1566.     STA    AR$STA    
  1567.     POP    PSW
  1568.     EI
  1569.     RET
  1570. ;    Here when data to follow
  1571. AR$S2S0    EQU    $
  1572.     PUSH    H        ; PRESERVE HL
  1573.     CALL    GCELL        ; GET A FREE CELL
  1574.     JZ    AR$S2S7        ; IF (BUFFERS FULL) GOTO AR$S0S7
  1575.     XCHG            ; HL <-- CELL POINTER
  1576.     SHLD    AR$BP        ; ESTABLISH NEW BUFFER POINTERS
  1577.     SHLD    AR$HC
  1578.     MVI    M,0        ; RESET FORWARD POINTER
  1579.     INX    H        ; ADVANCE POINTER
  1580.     MVI    M,0
  1581.     LXI    H,0        ; HL <-- 0
  1582.     SHLD    AR$FSZ        ; RESET FRAME SIZE
  1583.     POP    H        ; RESTORE HL
  1584.     XRA    A        ; NEW STATE
  1585.     STA    AR$STA        ; RECORD IT
  1586.     POP    PSW
  1587.     EI
  1588.     RET            ; RETURN FROM INTERRUPT
  1589.  
  1590. ;    Load a persistence value
  1591. AR$S3    EQU    $
  1592.     IN    RBR
  1593.     STA    PVAL
  1594.     MVI    A,2
  1595.     STA    AR$STA    
  1596.     POP    PSW
  1597.     EI
  1598.     RET
  1599.  
  1600. ;    Load a slot-time value
  1601. AR$S4    EQU    $
  1602.     IN    RBR
  1603.     STA    SVAL
  1604.     MVI    A,2
  1605.     STA    AR$STA    
  1606.     POP    PSW
  1607.     EI
  1608.     RET
  1609.  
  1610. ;    Load a squelch-delay value
  1611. AR$S5    EQU    $
  1612.     IN    RBR
  1613.     STA    TVAL
  1614.     MVI    A,2
  1615.     STA    AR$STA    
  1616.     POP    PSW
  1617.     EI
  1618.     RET
  1619.  
  1620. ;    Load a Tx relay delay value
  1621. AR$S6    EQU    $
  1622.     IN    RBR
  1623.     STA    RVAL
  1624.     MVI    A,2
  1625.     STA    AR$STA    
  1626.     POP    PSW
  1627.     EI
  1628.     RET
  1629. ;    PAGE
  1630.  
  1631. ;    Synchronous Transmitter Interrupt Response Code
  1632.  
  1633. STIRC    EQU    $
  1634.     PUSH    PSW        ; PRESERVE PROGRAM STATUS WORD
  1635.     PUSH    H        ; SAME WITH HL
  1636.     IN    STAT73        ; READ STATUS
  1637.     ANI    TXIRA
  1638.     JNZ    ST$CI        ; IF (END-OF-FRAME) GOTO ST$CI
  1639. ;    Here if transmitter waiting for data
  1640.     LHLD    ST$BP        ; HL <-- BUFFER POINTER
  1641.     CALL    GCHAR        ; MOVE NEXT CHARACTER TO A
  1642.     OUT    TXDR73        ; WRITE CHARACTER
  1643.     SHLD    ST$BP        ; SAVE UPDATED POINTER
  1644.     POP    H        ; RESTORE HL
  1645.     POP    PSW
  1646.     EI
  1647.     RET            ; RETURN FROM INTERRUPT
  1648.  
  1649. ;    Here for frame completion interrupt
  1650. ST$CI    EQU    $
  1651.     IN    TXIR73        ; READ RESULTS
  1652.     STA    ST$FR        ; SAVE RESULTS POINTER
  1653.     PUSH    D        ; PRESERVE DE
  1654.     LHLD    ST$BP        ; HL <-- CURRENT BUFFER POINTER
  1655.     XCHG            ; MOVE POINTER TO DE
  1656.     CALL    FCELL        ; FREE THIS CELL
  1657.     POP    D        ; RESTORE DE
  1658.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1659.     ORI    STFC        ; SYNC. TRANSMITTER FRAME COMPLETE
  1660.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1661.     POP    H        ; RESTORE HL
  1662.     POP    PSW
  1663.     EI
  1664.     RET            ; RETURN FROM INTERRUPT
  1665. ;    PAGE
  1666.  
  1667. ;    Synchronous Receiver Interrupt Response Code
  1668.  
  1669. SRIRC    EQU    $
  1670.     PUSH    PSW        ; PRESERVE PROGRAM STATUS WORD
  1671.     LDA    SR$STA        ; A <-- STATE OF SYNC. RECEIVER
  1672.     ORA    A
  1673.     JNZ    SR$S1        ; IF (DISCARDING DATA) GOTO SR$S1
  1674.  
  1675. ;    Here if synchronous receiver state 0, recording data
  1676. SR$S0    EQU    $
  1677.     PUSH    H        ; PRESERVE HL
  1678.     IN    STAT73        ; READ STATUS
  1679.     ANI    RXIRA
  1680.     JNZ    SR$CI        ; IF (END-OF-FRAME) GOTO SR$CI
  1681. ;    Here if receiver has data to unload
  1682.     IN    RXDR73        ; READ CHARACTER
  1683.     LHLD    SR$BP        ; HL <-- BUFFER POINTER
  1684.     CALL    PCHAR        ; COPY CHARACTER TO BUFFER
  1685.     JZ    SR$BF        ; IF (BUFFERS FULL) GOTO SR$BF
  1686.     SHLD    SR$BP        ; SAVE UPDATED POINTER
  1687.     POP    H        ; RESTORE HL
  1688.     POP    PSW
  1689.     EI
  1690.     RET            ; RETURN FROM INTERRUPT
  1691.  
  1692. ;    Here for frame completion interrupt
  1693. SR$CI    EQU    $
  1694.     IN    RXIR73        ; READ FRAME STATUS
  1695.     STA    SR$FR        ; SAVE IT FOR EXEC
  1696.     PUSH    B        ; PRESERVE BC
  1697. SR$CIA    EQU    $
  1698.     IN    STAT73        ; READ STATUS
  1699.     MOV    B,A        ; COPY STATUS TO B
  1700.     ANI    RINTP
  1701.     JZ    SR$CIB        ; IF (RESULTS COMPLETE) GOTO SR$CIB
  1702.     MOV    A,B        ; RESTORE STATUS
  1703.     ANI    RXIRA
  1704.     JZ    SR$CIA        ; IF (NO RESULTS) GOTO SR$CIA
  1705. ;    Ready to read one byte of results code
  1706.     IN    RXIR73        ; READ RESULTS
  1707.     JMP    SR$CIA        ; WAIT FOR MORE, IF ANY
  1708. ;    Results are now complete
  1709. SR$CIB    EQU    $
  1710.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1711.     ORI    SRFC        ; SYNC. RECEIVER FRAME COMPLETE
  1712.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1713.     POP    B        ; RESTORE BC
  1714.     POP    H        ; RESTORE HL
  1715.     POP    PSW
  1716.     EI
  1717.     RET            ; RETURN FROM INTERRUPT
  1718. ;    Again we must deal with being in the middle of a frame
  1719. ;    with no available free cells to continue.  Release the
  1720. ;    cells for this frame and cease reception till we recover.
  1721. SR$BF    EQU    $
  1722.     MVI    A,1        ; NEW STATE
  1723.     STA    SR$STA        ; RECORD IT
  1724.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1725.     ORI    SRDD        ; SYNC. RECEIVER DISCARDING DATA
  1726.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1727.     POP    H        ; RESTORE HL
  1728.     POP    PSW
  1729.     EI
  1730.     RET            ; RETURN FROM INTERRUPT
  1731.  
  1732. ;    Here if synchronous receiver state 1, discarding data
  1733. SR$S1    EQU    $
  1734.     IN    STAT73        ; READ STATUS
  1735.     ANI    RXIRA
  1736.     JNZ    SR$DR        ; IF (END-OF-FRAME) GOTO SR$DR
  1737. ;    Here if receiver has data to unload
  1738.     IN    RXDR73        ; READ CHARACTER
  1739.     POP    PSW
  1740.     EI
  1741.     RET            ; RETURN FROM INTERRUPT
  1742. ;    Here if discarding results
  1743. SR$DR    EQU    $
  1744.     IN    RXIR73        ; READ FRAME RESULTS
  1745.     PUSH    B        ; PRESERVE BC
  1746. SR$DRA    EQU    $
  1747.     IN    STAT73        ; READ STATUS
  1748.     MOV    B,A        ; COPY STATUS TO B
  1749.     ANI    RINTP
  1750.     JZ    SR$DRB        ; IF (RESULTS COMPLETE) GOTO SR$DRB
  1751.     MOV    A,B        ; RESTORE STATUS
  1752.     ANI    RXIRA
  1753.     JZ    SR$DRA        ; IF (NO RESULTS) GOTO SR$DRA
  1754. ;    Ready to read one byte of results code
  1755.     IN    RXIR73        ; READ RESULTS
  1756.     JMP    SR$DRA        ; WAIT FOR MORE, IF ANY
  1757. ;    Results are now complete
  1758. SR$DRB    EQU    $
  1759.     POP    B        ; RESTORE BC
  1760.     POP    PSW
  1761.     EI
  1762.     RET            ; RETURN FROM INTERRUPT
  1763. ;    PAGE
  1764.  
  1765. ;    Command and Immediate Results routines for 8273
  1766.  
  1767. SCMDOT    EQU    $
  1768.     MOV    B,M        ; B <-- PARAMETER COUNT
  1769.     INX    H        ; ADVANCE TO COMMAND BYTE
  1770. CMD1    EQU    $
  1771.     IN    STAT73        ; READ STATUS
  1772.     RLC            ; MOVE CBSY INTO CARRY
  1773.     JC    CMD1        ; IF (CBSY <> 0) GOTO CMD1
  1774.     MOV    A,M        ; A <-- COMMAND BYTE
  1775.     OUT    CMND73        ; WRITE COMMAND
  1776. CMD2    EQU    $
  1777.     MOV    A,B        ; A <-- PARAMETER COUNT
  1778.     ANA    A
  1779.     RZ            ; IF (COUNT = 0) RETURN
  1780.     INX    H        ; ADVANCE POINTER
  1781.     DCR    B        ; DECREMENT PARAMETER COUNT
  1782. CMD3    EQU    $
  1783.     IN    STAT73        ; READ STATUS
  1784.     ANI    CPBF        ; MASK COMMAND PARAMETER BUFFER FULL
  1785.     JNZ    CMD3        ; IF (CPBF <> 0) GOTO CMD3
  1786.     MOV    A,M        ; A <-- PARAMETER
  1787.     OUT    PARM73        ; WRITE PARAMETER
  1788.     JMP    CMD2        ; CHECK FOR MORE PARAMETERS
  1789.  
  1790.  
  1791.  
  1792. SRSLIN    EQU    $
  1793.     IN    STAT73        ; READ STATUS
  1794.     ANI    CRBF        ; MASK COMMAND RESULTS BUFFER FULL
  1795.     JZ    SRSLIN        ; IF (CRBF = 0) GOTO SRSLIN
  1796.     IN    RESL73        ; READ RESULTS
  1797.     RET
  1798. ;    PAGE
  1799.  
  1800. ;
  1801. ;    COMMAND SEQUENCES FOR 8273 CONTROLLER
  1802. DTRANS    DB    1,97H,1
  1803. OPMODE    DB    1,91H,03H
  1804. SERIO    DB    1,0A0H,1
  1805. SSDTR    DB    1,0A3H,4
  1806. STRTS    DB    1,0A3H,1
  1807. DARTS    DB    1,63H,0FEH
  1808. SRDIS    DB    0,0C5H
  1809. RPA    DB    0,22H
  1810.  
  1811. ;    Messages
  1812.  
  1813. ;
  1814. ;    TNC's SIGNATURE
  1815. TNCID    EQU    $
  1816.     DB    'VADCG/VDS1-'
  1817.     DB    'KISS Protocol Firmware Version 1.03A  10 SEP 87'
  1818.     DB    CR,LF,LF
  1819.  
  1820.     END
  1821.